package com.zjuee.gateway.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 加密工具类
 *
 * @author wu liang
 * @since 2020/8/13 9:54
 */
@Slf4j
public class EncryptUtil {


	/**
	 * 获取用户登录密码
	 * 根据用户名加盐加密后获取用户密码，此方法与shiro加密方法保持一致
	 */
	public static String encryPasswrod(String username,String password) {
		username = username == null ? "" : username;
		password = password == null ? "" : password;
		ByteSource credentialsSalt = ByteSource.Util.bytes(username);
		return new SimpleHash("MD5", password, credentialsSalt, 2).toHex();
	}


	/**
	 * 对一个字符串进行MD5加密
	 */
	public static String md5(String key,String content) {
		return encrypt(key, "MD5", content);
	}

	/**
	 * 对一个字符串进行 SHA-1加密
	 */
	public static String sha1(String key,String content) {
		return encrypt(key, "SHA-1", content);
	}

	/**
	 * 对一个字符串进行 SHA256加密
	 */
	public static String sha256(String key,String content) {
		return encrypt(key, "SHA-256", content);
	}

	// 获取加密工具实体
	public static String encrypt(String key, String type, String content) {
		try {
			MessageDigest md = MessageDigest.getInstance(type);
			md.update(content.getBytes());
			byte[] byteDigest = md.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < byteDigest.length; offset++) {
				i = byteDigest[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			// 32位加密
			return buf.toString();
			// 16位的加密
			// return buf.toString().substring(8, 24);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}
	}

    /**
     * 获取指定文件的MD5值
     */
    public static String getFileMD5(File file) {
        FileInputStream fis = null;
        try {
        	 MessageDigest md = MessageDigest.getInstance("MD5");
            fis = new FileInputStream(file);
            //100KB each time
            byte[] buffer = new byte[102400];
            int length;
            while ((length = fis.read(buffer)) != -1) {
                md.update(buffer, 0, length);
            }
            return new String(Hex.encodeHex(md.digest()));
        } catch (FileNotFoundException e) {
			log.error("md5 file " + file.getAbsolutePath() + " failed:" + e.getMessage());
            return null;
        } catch (IOException e) {
            log.error("md5 file " + file.getAbsolutePath() + " failed:" + e.getMessage());
            return null;
        } catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		} finally {
            try {
                if (fis != null) fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取字节流的MD5值
     */
    public static String getBytesMD5(byte[] uploadBytes) {
    	String hashString="";
    	try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] digest = md5.digest(uploadBytes);
			hashString = new String(Hex.encodeHex(digest));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	    return hashString;
    }


    /**
     * 拼接两个字节数组
     */
    public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){
        byte[] byte_3 = new byte[byte_1.length+byte_2.length];
        System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
        System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
        return byte_3;
    }
}
